package model

import (
	"errors"
	"gopkg.in/mgo.v2/bson"
	"src/config"
	"src/util"
)

type User struct {
	ID bson.ObjectId `bson:"_id,omitempty" json:"id,omitempty"`

	Name      string `bson:"name" json:"name"`
	Gender    int    `bson:"gender" json:"gender"`
	School    int    `bson:"school" json:"school"`
	Grade     string `bson:"grade" json:"grade"`
	AvatarUrl string `bson:"avatar_url" json:"avatar_url"`

	Openid      string   `bson:"openid" json:"openid"`
	Unionid     string   `bson:"unionid" json:"unionid"`
	ForumpostId []string `bson:"forumpost_id" json:"forumpost_id"`
}

func GetUserInfo(openid string) (User, error) {
	query := bson.M{
		"openid": openid,
	}
	u, err := findUser(query, DefaultSelector)
	if err != nil {
		return User{}, err
	}
	return u, nil
}

func ChangeUserMsg(user User) error {
	query := bson.M{
		"openid": user.Openid,
	}
	update := bson.M{
		"$set": bson.M{
			"name":   user.Name,
			"gender": user.Gender,
			"school": user.School,
			"grade":  user.Grade,
		},
	}
	return updateUser(query, update)
}

func ChangeUserImg(openid string, data *util.DecryptUserInfo) error {
	query := bson.M{
		"openid": openid,
	}
	update := bson.M{
		"$set": bson.M{
			"avatar_url": data.AvatarURL,
			//"gender":     data.Gender,
		},
	}
	return updateUser(query, update)
}

func CreatUser(userInfo WeixinSessRes, data *util.DecryptUserInfo) error {
	if userInfo.Openid != "" {
		query := bson.M{
			"openid": userInfo.Openid,
		}
		selector := bson.M{
			"openid": 1,
		}
		user, err := findUser(query, selector)
		if err != nil || user.Unionid == "" {
			user = User{}
			user.ID = bson.NewObjectId()
			user.Unionid = userInfo.Unionid
			user.Openid = userInfo.Openid
			user.Name = data.NickName
			user.AvatarUrl = data.AvatarURL
			user.School = -1
			user.Gender = data.Gender
			user.ForumpostId = nil
			return insertUser(user)
		}
		return nil
	}
	return errors.New("lack of the field opemid")

}

func AddForumpost(id, user_id string) error {
	query := bson.M{
		"openid": user_id,
	}
	update := bson.M{
		"$push": bson.M{
			"forumpost_id": id,
		},
	}
	return updateUser(query, update)
}
func DeleteUser_Forumpost(id, user_id string) error {
	if !bson.IsObjectIdHex(id) {
		return config.ErrorIDFormatWrong
	}
	query := bson.M{
		"openid": user_id,
	}
	update := bson.M{
		"$pull": bson.M{
			"forumpost_id": id,
		},
	}
	return updateUser(query, update)
}

/********************/
func updateUser(query, update interface{}) error {
	sess := globalSess.Clone()
	defer sess.Close()
	userTable := sess.DB(DBNAME).C(USERTABLE)

	return userTable.Update(query, update)
}

func insertUser(docs ...interface{}) error {
	sess := globalSess.Clone()
	defer sess.Close()
	userTable := sess.DB(DBNAME).C(USERTABLE)

	return userTable.Insert(docs...)
}
func findUser(query, selector interface{}) (User, error) {
	sess := globalSess.Copy()
	defer sess.Close()
	Table := sess.DB(DBNAME).C(USERTABLE)

	user := User{}
	err := Table.Find(query).Select(selector).One(&user)
	return user, err
}
